/*
 * Created on May 31, 2010
 */
package com.mgmaps.maps;

import com.nutiteq.components.MapTile;
import com.nutiteq.maps.MapTileOverlay;

public class GoogleLayers implements MapTileOverlay {
  
  public static final int MT_MAP = 0x0001;
  public static final int MT_SATELLITE = 0x0002;
  public static final int MT_TERRAIN_BG = 0x0004;
  public static final int MT_HYBRID_OVL = 0x0008;
  public static final int MT_TERRAIN_RIVERS = 0x0010;
  public static final int MT_TRAFFIC = 0x0020;
  public static final int MT_BIKE = 0x0040;
  public static final int MT_MAPMAKER_MAP = 0x0080;
  public static final int MT_MAPMAKER_HYB = 0x0100;
  public static final int MT_MAPMAKER_MOD_MAP = 0x0200;
  public static final int MT_MAPMAKER_MOD_HYB = 0x0400;
  public static final int MT_BG = MT_MAP | MT_SATELLITE | MT_TERRAIN_BG | MT_MAPMAKER_MAP;
  public static final int MT_MAPMAKER = MT_MAPMAKER_MAP | MT_MAPMAKER_HYB;
  public static final int MT_MAPMAKER_MOD = MT_MAPMAKER_MOD_MAP | MT_MAPMAKER_MOD_HYB;
  
  public static final int MAP_HYBRID = MT_SATELLITE | MT_HYBRID_OVL;
  public static final int MAP_TERRAIN = MT_TERRAIN_BG | MT_TERRAIN_RIVERS;
  public static final int MAP_MAPMAKER_HYB = MT_SATELLITE | MT_MAPMAKER_HYB;
  public static final int MAP_MAPMAKER_MOD = MT_MAPMAKER_MAP | MT_MAPMAKER_MOD_MAP;  
  public static final int MAP_MAPMAKER_MOD_HYB = MT_SATELLITE | MT_MAPMAKER_HYB | MT_MAPMAKER_MOD_HYB;  
  
  public static final GoogleLayers LAYER_SATELLITE = new GoogleLayers(MT_SATELLITE);

  private int layers;
  
  private static final String[] LAYER = { "m", "", "t", "h", "r", "traffic|seconds_into_week:-1", "bike", "", "", "m", "h" };
  // private static final String[] VERSIONS = { "127", "62", "125", "127", "127", "", "", "gwm.1326", "gwh.1326" };
  private static final String[] VERSIONS = { "999", "62", "999", "999", "999", "", "", "gwm.fresh", "gwh.fresh", "", "" };
  private static final int NUM_LAYERS = LAYER.length;
  private static final int MT_SATELLITE_LOG = 1;
  private static final String LANGUAGE = "en";
  private static final String GALILEO = "Galileo";
  
  public GoogleLayers(final int layers) {
    this.layers = layers;
  }
  
  public String getOverlayTileUrl(final MapTile tile) {
    final int tmpX = tile.getX() >> 8;
    final int tmpY = tile.getY() >> 8;
    final int zoom = tile.getZoom();
    
    return buildPath(tmpX, tmpY, zoom);
  }
  
  public String buildPath(final int tmpX, final int tmpY, final int zoom) {
    StringBuffer buf = new StringBuffer();
    if ((layers & MT_SATELLITE) != 0) {
      buf.append("http://khm");
      buf.append(tmpX & 1);
      buf.append(".google.com/kh/v=");
      buf.append(VERSIONS[MT_SATELLITE_LOG]);
    }
    else if ((layers & MT_MAPMAKER) != 0) {
      buf.append("http://gt");
      buf.append((tmpX + 3*tmpY) & 3);
      buf.append(".google.com/mt/n=404&v=");
      for (int i=0; i<NUM_LAYERS; i++)
        if ((layers & (1<<i)) != 0) {
          buf.append(VERSIONS[i]);
          break;
        }
    }
    else if ((layers & MT_MAPMAKER_MOD) != 0) {
      buf.append("http://gw");
      buf.append((tmpX + 3*tmpY) & 3);
      buf.append(".google.com/mt?t=");
      for (int i=0; i<NUM_LAYERS; i++)
        if ((layers & (1<<i)) != 0) {
          buf.append(LAYER[i]);
          break;
        }
      buf.append("&gw=31&ts=");
      buf.append(System.currentTimeMillis());
    }
    else {
      buf.append("http://mt");
      buf.append(tmpX & 1);
      buf.append(".google.com/vt?lyrs=");
      boolean hasLayers = false;
      for (int i=0; i<NUM_LAYERS; i++)
        if ((layers & (1<<i)) != 0) {
          if (hasLayers)
            buf.append(',');
          else
            hasLayers = true;
          buf.append(LAYER[i]);
          if (VERSIONS[i].length() > 0)
            buf.append('@' + VERSIONS[i]);
        }
      buf.append("&hl=" + LANGUAGE);
    }
    buf.append("&x=" + tmpX);
    buf.append("&y=" + tmpY);
    buf.append("&z=" + zoom);
    if ((layers & MT_MAPMAKER) == 0 && (layers & MT_MAPMAKER_MOD) == 0)
      buf.append("&s=" + GALILEO.substring(0, ((3*tmpX+tmpY)&7)));
    return buf.toString();
  }
}
